package com.taobao.home.jobhandler;


import com.taobao.base.model.RestResponse;
import com.taobao.home.model.po.Process;
import com.taobao.home.service.GoodsService;
import com.taobao.home.service.ProcessService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 任务处理类
 */

@Slf4j
@Component
public class HomeTask {

    @Autowired
    private ProcessService processService;

    @Autowired
    private GoodsService goodsService;


    /**
     * 商品文档操作
     */
    @XxlJob("goodsJobHandler")
    public void goodsJobHandler() throws Exception {

        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();//执行器的序号，从0开始
        int shardTotal = XxlJobHelper.getShardTotal();//执行器总数

        //确定cpu的核心数
        int processors = Runtime.getRuntime().availableProcessors();
        //查询待处理的任务
        List<Process> processList = processService.getProcessList(shardIndex, shardTotal, processors);

        //任务数量
        int size = processList.size();
        log.debug("取到视频处理任务数:" + size);
        if (size <= 0) {
            return;
        }
        //创建一个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(size);
        //使用的计数器
        CountDownLatch countDownLatch = new CountDownLatch(size);
        processList.forEach(process -> {
            //将任务加入线程池
            executorService.execute(() -> {
                try {
                    //任务id
                    long taskId = process.getId();
                    // 文件id
                    int fileId = process.getFileId();
                    //开启任务
                    boolean b = processService.startTask(taskId);
                    if (!b) {
                        log.debug("抢占任务失败,任务id:{}", taskId);
                        return;
                    }
                    //执行任务
                    if (taskId == 7) {  // 为什么id==7会失败啊??
                        log.debug("出错,任务id:{}", taskId);
                        //保存任务处理失败的结果
                        processService.saveProcessFinishStatus(taskId, "3", "...失败");
                        return;
                    }
                    switch (process.getTypes()) {
                        case 1:
                            // 添加商品文档
                            addGoodsDoc(taskId, fileId);
                            break;
                        case 2:
                            // 删除商品文档
                            break;
                        case 3:
                            // 添加商店文档
                            break;
                        case 4:
                            // 删除
                            break;
                    }

                } finally {
                    //计算器减去1
                    countDownLatch.countDown();
                }

            });

        });

        //阻塞,指定最大限制的等待时间，阻塞最多等待一定的时间后就解除阻塞
        countDownLatch.await(30, TimeUnit.MINUTES);


    }

    private void addGoodsDoc(long taskId, int fileId) {

        RestResponse<String> stringRestResponse = goodsService.addGoodsDoc(fileId);

        if (stringRestResponse.getCode() == 0) {
            //更新任务状态为成功
            processService.saveProcessFinishStatus(taskId, "2", stringRestResponse.getMsg());
        } else {
            //更新任务状态为失败
            processService.saveProcessFinishStatus(taskId, "2", stringRestResponse.getMsg());
        }
    }

}
